#if (1 == USE_AUTO_TUNE)
int afrcalc_table(unsigned int16 rpm, unsigned int16 map, char inj)  {
    signed int ix,jx;
    int32 interp1, interp2, interp3;

    // returns AFR x 10
    // bound input arguments
    if(rpm > in_parm.frpm_table[NO_FRPMS-1]) {
        rpm = in_parm.frpm_table[NO_FRPMS-1];
    } else if (rpm < in_parm.frpm_table[0]) {
        rpm = in_parm.frpm_table[0];
    }

    if (map > in_parm.fmap_table[NO_FMAPS-1]) {
        map = in_parm.fmap_table[NO_FMAPS-1];
    } else if (map < in_parm.fmap_table[0]) {
        map = in_parm.fmap_table[0];
    }

    // Look up AFR in table
    for(ix = NO_FMAPS - 2; ix > -1; ix--)  {  // Start w highest index
    //  because will have least time for calculations at hi maps
        if(map > in_parm.fmap_table[ix])  {
            break;
        }
    }
    if(ix < 0)ix = 0;

    for(jx = NO_FRPMS - 2; jx > -1; jx--)  {  // Start w highest index
        // because will have least time for calculations at hi rpms
        if(rpm > in_parm.frpm_table[jx])  {
            break;
        }
    }

    if(jx < 0)jx = 0;

    interp1 = in_parm.fmap_table[ix + 1] - in_parm.fmap_table[ix] ;

    if(interp1 != 0)  {
        interp3 = (map - in_parm.fmap_table[ix]); 
        interp3 = (100 * interp3); 
        interp1 = interp3 / interp1; 
    }
    interp2 = in_parm.frpm_table[jx + 1] - in_parm.frpm_table[jx];

    if(interp2 != 0) {
        interp3 = (rpm - in_parm.frpm_table[jx]);
        interp3 = (100 * interp3);
        interp2 = interp3 / interp2;
    }
    return((int)(((100 - interp1) * (100 - interp2) * in_parm.afr_table[(int)inj][ix][jx]
      + interp1 * (100 - interp2) * in_parm.afr_table[(int)inj][ix+1][jx]
      + interp2 * (100 - interp1) * in_parm.afr_table[(int)inj][ix][jx+1]
      + interp1 * interp2 * in_parm.afr_table[(int)inj][ix+1][jx+1]) / 10000));
                            // AFR x 10
}
#endif

void calc_wb_corretions (void)
{
#if (1 == USE_AUTO_TUNE)
    signed int16 egostep;

    if( (in_parm.EgoOption == 0) ||
        (out_parm.rpm < in_parm.RPMOXLimit) ||
        (out_parm.engine & 0x30) ||                // engine accel/ decel
        (out_parm.clt < in_parm.EgoTemp) ||
        (out_parm.tps > in_parm.TPSOXLimit) ||
        (out_parm.map > in_parm.MAPOXLimit) ||
        (out_parm.seconds < 5))  {                // wait about 3min before start closed loop control
            out_parm.egocor1 = out_parm.egocor2 = 100;
        return;//goto VETABLELOOKUP;
    }

    if(egocount < in_parm.EgoCountCmp) {
        return; //goto VETABLELOOKUP;
    }
    // check if rich/ lean after every EgoCountCmp ignition pulses
    egocount = 0;

    if(in_parm.EgoOption >= 2)  {
        // WBO2
        out_parm.afrtgt1 = (unsigned char)afrcalc_table(out_parm.rpm, k_pa, 0); 
                                                               // afr x 10
        if(in_parm.dual_tble_optn)
            out_parm.afrtgt2 = (unsigned char)afrcalc_table(out_parm.rpm, k_pa, 1);
                                                               // afr x 10
        else
          out_parm.afrtgt2 = out_parm.afrtgt1;

        if(out_parm.wbo2_en2)  {
           
            egostep = (signed int16) ((out_parm.ego2 - out_parm.afrtgt2) * 100)/out_parm.afrtgt2;
            if(egostep > 0)  {
            // O2_IS_LEAN
            if((out_parm.egocor2 + egostep) <= (100 + in_parm.EgoLimit))
                out_parm.egocor2 += egostep;               // egocor not railed
            else
              out_parm.egocor2 = 100 + in_parm.EgoLimit;    // railed
            } else {
                egostep = -egostep;
                // O2_IS_RICH
                if((out_parm.egocor2 -egostep) >= (100 - in_parm.EgoLimit))
                    out_parm.egocor2 -= egostep;                 // egocor not railed
                else
                    out_parm.egocor2 = 100 - in_parm.EgoLimit;    // railed
            }
        }

        if(out_parm.wbo2_en1)  {
            egostep = (signed int16) ((out_parm.ego1 - out_parm.afrtgt1) * 100)/out_parm.afrtgt1;
            if(egostep > 0)  {
            // O2_IS_LEAN
            if((out_parm.egocor1 + egostep) <= (100 + in_parm.EgoLimit))
                out_parm.egocor1 += egostep;               // egocor not railed
            else
              out_parm.egocor1 = 100 + in_parm.EgoLimit;    // railed
            } else {
                egostep = -egostep;
                // O2_IS_RICH
                if((out_parm.egocor1 -egostep) >= (100 - in_parm.EgoLimit))
                    out_parm.egocor1 -= egostep;                 // egocor not railed
                else
                    out_parm.egocor1 = 100 - in_parm.EgoLimit;    // railed
            }
        }
    }
#else
    out_parm.egocor1 = out_parm.egocor2 = 100;
#endif
}

